home *** CD-ROM | disk | FTP | other *** search
/ Aminet 40 / Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso / Aminet / dev / lang / Python16_Src.lha / Python16_Source / Modules / mathmodule.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-09-10  |  8.3 KB  |  315 lines

  1. /* Math module -- standard C math library functions, pi and e */
  2.  
  3. #include "Python.h"
  4.  
  5. #include "mymath.h"
  6. #include "protos/mathmodule.h"
  7.  
  8. #ifndef _MSC_VER
  9. #ifndef __STDC__
  10. extern double fmod Py_PROTO((double, double));
  11. extern double frexp Py_PROTO((double, int *));
  12. extern double ldexp Py_PROTO((double, int));
  13. extern double modf Py_PROTO((double, double *));
  14. #endif /* __STDC__ */
  15. #endif /* _MSC_VER */
  16.  
  17.  
  18. #ifdef i860
  19. /* Cray APP has bogus definition of HUGE_VAL in <math.h> */
  20. #undef HUGE_VAL
  21. #endif
  22.  
  23. #ifdef HUGE_VAL
  24. #define CHECK(x) if (errno != 0) ; \
  25.     else if (-HUGE_VAL <= (x) && (x) <= HUGE_VAL) ; \
  26.     else errno = ERANGE
  27. #else
  28. #define CHECK(x) /* Don't know how to check */
  29. #endif
  30.  
  31. static PyObject *
  32. math_error()
  33. {
  34.     if (errno == EDOM)
  35.         PyErr_SetString(PyExc_ValueError, "math domain error");
  36.     else if (errno == ERANGE)
  37.         PyErr_SetString(PyExc_OverflowError, "math range error");
  38.     else
  39.                 /* Unexpected math error */
  40.         PyErr_SetFromErrno(PyExc_ValueError);
  41.     return NULL;
  42. }
  43.  
  44. #ifdef __SASC
  45. static PyObject *math_post_f(double x)
  46. {
  47.     CHECK(x);
  48.     if(errno!=0) return math_error();
  49.     else return PyFloat_FromDouble(x);
  50. }
  51.  
  52. #define FUNC1(stubname, func, docstring_name, docstring) \
  53.     static PyObject * stubname(PyObject *self, PyObject*args) { \
  54.     double x; if (!PyArg_Parse(args, "d", &x)) return NULL; \
  55.     errno = 0; PyFPE_START_PROTECT("in math_1", return 0) \
  56.     x=func(x);     PyFPE_END_PROTECT(x) return math_post_f(x); } \
  57.         static char docstring_name [] = docstring;
  58.  
  59. #define FUNC2(stubname, func, docstring_name, docstring) \
  60.     static PyObject * stubname(PyObject *self, PyObject *args) { \
  61.     double x, y; if(!PyArg_Parse(args, "(dd)", &x, &y)) return NULL; \
  62.     errno = 0; PyFPE_START_PROTECT("in math_2", return 0) \
  63.     x = func(x, y); PyFPE_END_PROTECT(x) return math_post_f(x); } \
  64.         static char docstring_name [] = docstring;
  65. #else /* !__SASC */
  66. static PyObject *
  67. math_1(args, func)
  68.     PyObject *args;
  69.     double (*func) Py_FPROTO((double));
  70. {
  71.     double x;
  72.     if (!  PyArg_Parse(args, "d", &x))
  73.         return NULL;
  74.     errno = 0;
  75.     PyFPE_START_PROTECT("in math_1", return 0)
  76.     x = (*func)(x);
  77.     PyFPE_END_PROTECT(x)
  78.     CHECK(x);
  79.     if (errno != 0)
  80.         return math_error();
  81.     else
  82.         return PyFloat_FromDouble(x);
  83. }
  84.  
  85. static PyObject *
  86. math_2(args, func)
  87.     PyObject *args;
  88.     double (*func) Py_FPROTO((double, double));
  89. {
  90.     double x, y;
  91.     if (! PyArg_Parse(args, "(dd)", &x, &y))
  92.         return NULL;
  93.     errno = 0;
  94.     PyFPE_START_PROTECT("in math_2", return 0)
  95.     x = (*func)(x, y);
  96.     PyFPE_END_PROTECT(x)
  97.     CHECK(x);
  98.     if (errno != 0)
  99.         return math_error();
  100.     else
  101.         return PyFloat_FromDouble(x);
  102. }
  103.  
  104. #ifdef HAVE_PROTOTYPES
  105. #define FUNC1(stubname, func, docstring_name, docstring) \
  106.     static PyObject * stubname(PyObject *self, PyObject *args) { \
  107.         return math_1(args, func); \
  108.     }\
  109.         static char docstring_name [] = docstring;
  110.  
  111. #define FUNC2(stubname, func, docstring_name, docstring) \
  112.     static PyObject * stubname(PyObject *self, PyObject *args) { \
  113.         return math_2(args, func); \
  114.     }\
  115.         static char docstring_name [] = docstring;
  116. #else /* !HAVE_PROTOTYPES */
  117. #define FUNC1(stubname, func, docstring_name, docstring) \
  118.     static PyObject * stubname(self, args) PyObject *self, *args; { \
  119.         return math_1(args, func); \
  120.     }\
  121.         static char docstring_name [] = docstring;
  122.  
  123. #define FUNC2(stubname, func, docstring_name, docstring) \
  124.     static PyObject * stubname(self, args) PyObject *self, *args; { \
  125.         return math_2(args, func); \
  126.     }\
  127.         static char docstring_name [] = docstring;
  128.  
  129. #endif /* HAVE_PROTOTYPES */
  130. #endif /* !__SASC */
  131.  
  132. FUNC1(math_acos, acos, math_acos_doc,
  133.       "acos(x)\n\nReturn the arc cosine of x.")
  134. FUNC1(math_asin, asin, math_asin_doc,
  135.       "asin(x)\n\nReturn the arc sine of x.")
  136. FUNC1(math_atan, atan, math_atan_doc,
  137.       "atan(x)\n\nReturn the arc tangent of x.")
  138. FUNC2(math_atan2, atan2, math_atan2_doc,
  139.       "atan2(y, x)\n\nReturn atan(y/x).")
  140. FUNC1(math_ceil, ceil, math_ceil_doc,
  141.       "ceil(x)\n\nReturn the ceiling of x as a real.")
  142. FUNC1(math_cos, cos, math_cos_doc,
  143.       "cos(x)\n\nReturn the cosine of x.")
  144. FUNC1(math_cosh, cosh, math_cosh_doc,
  145.       "cosh(x)\n\nReturn the hyperbolic cosine of x.")
  146. FUNC1(math_exp, exp, math_exp_doc,
  147.       "exp(x)\n\nReturn e raised to the power of x.")
  148. FUNC1(math_fabs, fabs, math_fabs_doc,
  149.       "fabs(x)\n\nReturn the absolute value of the real x.")
  150. FUNC1(math_floor, floor, math_floor_doc,
  151.       "floor(x)\n\nReturn the floor of x as a real.")
  152. FUNC2(math_fmod, fmod, math_fmod_doc,
  153.       "fmod(x,y)\n\nReturn x % y.")
  154. FUNC2(math_hypot, hypot, math_hypot_doc,
  155.       "hypot(x,y)\n\nReturn the Euclidean distance, sqrt(x*x + y*y).")
  156. FUNC1(math_log, log, math_log_doc,
  157.       "log(x)\n\nReturn the natural logarithm of x.")
  158. FUNC1(math_log10, log10, math_log10_doc,
  159.       "log10(x)\n\nReturn the base-10 logarithm of x.")
  160. #ifdef MPW_3_1 /* This hack is needed for MPW 3.1 but not for 3.2 ... */
  161. FUNC2(math_pow, power, math_pow_doc,
  162.       "power(x,y)\n\nReturn x**y.")
  163. #else
  164. FUNC2(math_pow, pow, math_pow_doc,
  165.       "pow(x,y)\n\nReturn x**y.")
  166. #endif
  167. FUNC1(math_sin, sin, math_sin_doc,
  168.       "sin(x)\n\nReturn the sine of x.")
  169. FUNC1(math_sinh, sinh, math_sinh_doc,
  170.       "sinh(x)\n\nReturn the hyperbolic sine of x.")
  171. FUNC1(math_sqrt, sqrt, math_sqrt_doc,
  172.       "sqrt(x)\n\nReturn the square root of x.")
  173. FUNC1(math_tan, tan, math_tan_doc,
  174.       "tan(x)\n\nReturn the tangent of x.")
  175. FUNC1(math_tanh, tanh, math_tanh_doc,
  176.       "tanh(x)\n\nReturn the hyperbolic tangent of x.")
  177.  
  178.  
  179. static PyObject *
  180. math_frexp(self, args)
  181.     PyObject *self;
  182.     PyObject *args;
  183. {
  184.     double x;
  185.     int i;
  186.     if (! PyArg_Parse(args, "d", &x))
  187.         return NULL;
  188.     errno = 0;
  189.     x = frexp(x, &i);
  190.     CHECK(x);
  191.     if (errno != 0)
  192.         return math_error();
  193.     return Py_BuildValue("(di)", x, i);
  194. }
  195.  
  196. static char math_frexp_doc [] =
  197. "frexp(x)\n\
  198. \n\
  199. Return the matissa and exponent for x. The mantissa is positive.";
  200.  
  201.  
  202. static PyObject *
  203. math_ldexp(self, args)
  204.     PyObject *self;
  205.     PyObject *args;
  206. {
  207.     double x;
  208.     int exp;
  209.     if (! PyArg_Parse(args, "(di)", &x, &exp))
  210.         return NULL;
  211.     errno = 0;
  212.     PyFPE_START_PROTECT("ldexp", return 0)
  213.     x = ldexp(x, exp);
  214.     PyFPE_END_PROTECT(x)
  215.     CHECK(x);
  216.     if (errno != 0)
  217.         return math_error();
  218.     else
  219.         return PyFloat_FromDouble(x);
  220. }
  221.  
  222. static char math_ldexp_doc [] = 
  223. "ldexp_doc(x, i)\n\
  224. \n\
  225. Return x * (2**i).";
  226.  
  227.  
  228. static PyObject *
  229. math_modf(self, args)
  230.     PyObject *self;
  231.     PyObject *args;
  232. {
  233.     double x, y;
  234.     if (! PyArg_Parse(args, "d", &x))
  235.         return NULL;
  236.     errno = 0;
  237. #ifdef MPW /* MPW C modf expects pointer to extended as second argument */
  238. {
  239.     extended e;
  240.     x = modf(x, &e);
  241.     y = e;
  242. }
  243. #else
  244.     x = modf(x, &y);
  245. #endif
  246.     CHECK(x);
  247.     if (errno != 0)
  248.         return math_error();
  249.     return Py_BuildValue("(dd)", x, y);
  250. }
  251.  
  252. static char math_modf_doc [] =
  253. "modf(x)\n\
  254. \n\
  255. Return the fractional and integer parts of x. Both results carry the sign\n\
  256. of x.  The integer part is returned as a real.";
  257.  
  258.  
  259. static PyMethodDef math_methods[] = {
  260.     {"acos",    math_acos,    0,    math_acos_doc},
  261.     {"asin",    math_asin,    0,    math_asin_doc},
  262.     {"atan",    math_atan,    0,    math_atan_doc},
  263.     {"atan2",    math_atan2,    0,    math_atan2_doc},
  264.     {"ceil",    math_ceil,    0,    math_ceil_doc},
  265.     {"cos",        math_cos,    0,    math_cos_doc},
  266.     {"cosh",    math_cosh,    0,    math_cosh_doc},
  267.     {"exp",        math_exp,    0,    math_exp_doc},
  268.     {"fabs",    math_fabs,    0,    math_fabs_doc},
  269.     {"floor",    math_floor,    0,    math_floor_doc},
  270.     {"fmod",    math_fmod,    0,    math_fmod_doc},
  271.     {"frexp",    math_frexp,    0,    math_frexp_doc},
  272.     {"hypot",    math_hypot,    0,    math_hypot_doc},
  273.     {"ldexp",    math_ldexp,    0,    math_ldexp_doc},
  274.     {"log",        math_log,    0,    math_log_doc},
  275.     {"log10",    math_log10,    0,    math_log10_doc},
  276.     {"modf",    math_modf,    0,    math_modf_doc},
  277.     {"pow",        math_pow,    0,    math_pow_doc},
  278.     {"sin",        math_sin,    0,    math_sin_doc},
  279.     {"sinh",    math_sinh,    0,    math_sinh_doc},
  280.     {"sqrt",    math_sqrt,    0,    math_sqrt_doc},
  281.     {"tan",        math_tan,    0,    math_tan_doc},
  282.     {"tanh",    math_tanh,    0,    math_tanh_doc},
  283.     {NULL,        NULL}        /* sentinel */
  284. };
  285.  
  286.  
  287. static char module_doc [] =
  288. "This module is always available.  It provides access to the\n\
  289. mathematical functions defined by the C standard.";
  290.  
  291. DL_EXPORT(void)
  292. initmath()
  293. {
  294.     PyObject *m, *d, *v;
  295.     
  296.     m = Py_InitModule3("math", math_methods, module_doc);
  297.     d = PyModule_GetDict(m);
  298.  
  299.         if (!(v = PyFloat_FromDouble(atan(1.0) * 4.0)))
  300.                 goto finally;
  301.     if (PyDict_SetItemString(d, "pi", v) < 0)
  302.                 goto finally;
  303.     Py_DECREF(v);
  304.  
  305.         if (!(v = PyFloat_FromDouble(exp(1.0))))
  306.                 goto finally;
  307.     if (PyDict_SetItemString(d, "e", v) < 0)
  308.                 goto finally;
  309.     Py_DECREF(v);
  310.     return;
  311.  
  312.   finally:
  313.         Py_FatalError("can't initialize math module");
  314. }
  315.